package com.itheima.stock.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.itheima.stock.entity.*;
import com.itheima.stock.mapper.*;
import com.itheima.stock.properties.MarketIndexProperties;
import com.itheima.stock.response.PageResult;
import com.itheima.stock.service.StockService;
import com.itheima.stock.util.DateTimeUtil;
import com.itheima.stock.vo.*;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.MathContext;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class StockServiceImpl implements StockService {
    //股票交易信息
    private final StockRtInfoMapper stockRtInfoMapper;
    //板块
    private final StockBlockRtInfoMapper stockBlockRtInfoMapper;
    //大盘指数
    private final StockMarketIndexInfoMapper marketIndexInfoMapper;
    //大盘开盘收盘记录
    private final StockMarketLogPriceMapper marketLogPriceMapper;
    //大盘指数编码属性类
    private final StockBusinessMapper stockBusinessMapper;
    //股票业务信息
    private final MarketIndexProperties makerIndexProperties;
    private final StockMarketIndexInfoMapper stockMarketIndexInfoMapper;

    public StockServiceImpl(StockBusinessMapper stockBusinessMapper, MarketIndexProperties makerIndexProperties, StockMarketIndexInfoMapper marketIndexInfoMapper, StockMarketLogPriceMapper marketLogPriceMapper, StockBlockRtInfoMapper stockBlockRtInfoMapper, StockRtInfoMapper stockRtInfoMapper, StockMarketIndexInfoMapper stockMarketIndexInfoMapper) {
        this.stockBusinessMapper = stockBusinessMapper;
        this.makerIndexProperties = makerIndexProperties;
        this.marketIndexInfoMapper = marketIndexInfoMapper;
        this.marketLogPriceMapper = marketLogPriceMapper;
        this.stockBlockRtInfoMapper = stockBlockRtInfoMapper;
        this.stockRtInfoMapper = stockRtInfoMapper;
        this.stockMarketIndexInfoMapper = stockMarketIndexInfoMapper;
    }

    /*
    --------------------------------------------------------------------------------------------
     */

    @Override
    public List<IncreaseVO> selectStockInCrease() {
        //获取时间
        LocalDateTime last = DateTimeUtil.getLastDateTime4Stock(LocalDateTime.now());

        //TODO
        last = LocalDateTime.parse("2021-12-30 09:32:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        //TODO
        //从数据库中获取当前这一分钟所有的股票数据
        List<StockRtInfo> stockRtInfoList = stockRtInfoMapper.selectByTime(last);
        List<IncreaseVO> result = new ArrayList<>();
        stockRtInfoList.stream().forEach((stock)->{
            //创建一个VO
            IncreaseVO vo = new IncreaseVO();
            vo.setName(stock.getStockName());//名称
            vo.setCode(stock.getStockCode());//代码
            vo.setTradePrice(stock.getCurPrice());//现价
            vo.setPreClosePrice(stock.getPreClosePrice());//现价
            vo.setCurDate(stock.getCurTime().toLocalDate().format(DateTimeFormatter.ofPattern("yyyyMMdd")));//前收盘价
            vo.setTradeVol(stock.getTradeVolume());//成交额
            vo.setTradeAmt(stock.getTradeAmount());//总手
            //计算涨跌
            BigDecimal upDown = stock.getCurPrice().subtract(stock.getPreClosePrice());
            //计算涨幅
            BigDecimal increase = (stock.getCurPrice().subtract(stock.getPreClosePrice())).divide(stock.getPreClosePrice(),new MathContext(6)).multiply(new BigDecimal(1.0));
            //计算振幅
            BigDecimal range = (stock.getMaxPrice().subtract(stock.getMinPrice())).divide(stock.getPreClosePrice(),new MathContext(6)).multiply(new BigDecimal(1.0));
            vo.setIncrease(increase);
            vo.setUpDown(upDown);
            vo.setAmplitude(range);
            result.add(vo);
        });
        List<IncreaseVO> list = result.stream().sorted((o1, o2) -> o2.getIncrease().compareTo(o1.getIncrease())).limit(10).toList();
        return list;
    }

    @Override
    public TradevolVO<OptionVo> tradeAmt() {
        //t日
        LocalDateTime t = DateTimeUtil.getLastDateTime4Stock(LocalDateTime.now());
        //计算t日开盘时间
        LocalDateTime t_openDate = DateTimeUtil.getOpenDate(t);
        //计算t日收盘时间
        LocalDateTime t_closeDate = DateTimeUtil.getCloseDate(t);
        //t-1日
        LocalDateTime t_1 = DateTimeUtil.getPreviousTradingDay(t);
        //计算t-1日开盘时间
        LocalDateTime t_1_openDate = DateTimeUtil.getOpenDate(t_1);
        //计算t-1日收盘时间
        LocalDateTime t_1_closeDate = DateTimeUtil.getCloseDate(t_1);
        //TODO moke data
        t_openDate = LocalDateTime.parse("2021-12-28 09:30:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        t_closeDate = LocalDateTime.parse("2021-12-28 14:30:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));

        t_1_openDate = LocalDateTime.parse("2021-12-27 09:30:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        t_1_closeDate = LocalDateTime.parse("2021-12-27 14:30:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        //TODO moke data
        //查询数据
        List<String> ids = makerIndexProperties.getInner();
        List<OptionVo> list = stockMarketIndexInfoMapper.selectCountByTime(t_1_openDate, t_closeDate, ids);
        LocalDate tData = t_openDate.toLocalDate();
        LocalDate t_1Data = t_1_openDate.toLocalDate();
        List<OptionVo> tlist = list.stream().filter((vo) -> {
            LocalDateTime parse = LocalDateTime.parse(vo.getTime(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            LocalDate localDate = parse.toLocalDate();
            return localDate.isEqual(tData);
        }).toList();

        List<OptionVo> t_1list = list.stream().filter((vo) -> {
            LocalDateTime parse = LocalDateTime.parse(vo.getTime(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            LocalDate localDate = parse.toLocalDate();
            return localDate.isEqual(t_1Data);
        }).toList();
        //组装数据
        return TradevolVO.<OptionVo>builder()
                .volList(tlist)
                .yesVolList(t_1list)
                .build();
    }

    @Override
    public UpDownVO<OptionVo> UpDown() {
        LocalDateTime stock = DateTimeUtil.getLastDateTime4Stock(LocalDateTime.now());
        //TODO
        LocalDateTime begin = LocalDateTime.parse("2022-01-06 09:25:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        //TODO
        LocalDateTime end = LocalDateTime.parse("2022-01-06 14:25:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        /*
        应为这两条sql查询语句几乎一样，所以这边可以再加入一个boolean参数，用来比较，如果是true就是涨停，如果是false就是跌停
         */

        //涨停
        List<OptionVo> upList = stockRtInfoMapper.selectUpOrDown(begin,end,true);
        //跌停
        List<OptionVo> Down = stockRtInfoMapper.selectUpOrDown(begin,end,false);

        return UpDownVO.<OptionVo>builder()
                .upList(upList)
                .downList(Down)
                .build();
    }

    @Override
    public PageResult<MoreVO> more(Integer page, Integer pageSize) {
        //获取当前时间，离交易时间最近的时间
        LocalDateTime last1 = DateTimeUtil.getLastDateTime4Stock(LocalDateTime.now());
        //TODO 模拟数据
        final LocalDateTime last = LocalDateTime.parse("2021-12-30 09:32:00",DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        //TODO
        Page<MoreVO> result = PageHelper.startPage(page,pageSize).doSelectPage(()->{
            List<MoreVO> voList = stockRtInfoMapper.selectMove(last);
        });

        //组装数据
        return PageResult.<MoreVO>builder()
                .size(result.size())
                .totalRows(result.getTotal())
                .totalPages(result.getPages())
                .pageNum(result.getPageNum())
                .pageSize(result.getPageSize())
                .rows(result.getResult())
                .build();
    }

    @Override
    public List<StockBlockInfoVO> stockControllerApi() {

        //1、获取当前时间  2、查询前10条数据  3、根据时间降序查询
        LocalDateTime dateTime4Stock = DateTimeUtil.getLastDateTime4Stock(LocalDateTime.now());
        //TODO 虚拟数据
        dateTime4Stock = LocalDateTime.parse("2021-12-21 00:00:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        LocalDateTime begin = DateTimeUtil.getOpenDate(dateTime4Stock);
        LocalDateTime end = DateTimeUtil.getCloseDate(dateTime4Stock);
        //TODO 虚拟数据

        //模块数据集合
        List<StockBlockRtInfo> blockRtInfoList = stockBlockRtInfoMapper.stockControllerApi(begin,end);
        //数据组合
        return blockRtInfoList.stream().map((blockRtInfo)-> StockBlockInfoVO.builder()
                .name(blockRtInfo.getBlockName())
                .code(blockRtInfo.getLabel())
                .avgPrice(blockRtInfo.getAvgPrice())
                .companyNum(blockRtInfo.getCompanyNum())
                .curDate(blockRtInfo.getCurTime().toLocalDate().toString())
                .tradeAmt(blockRtInfo.getTradeAmount())
                .tradeVol(blockRtInfo.getTradeVolume())
                .updownRate(blockRtInfo.getUpdownRate())
                .build()).toList();
    }

    @Override
    public List<MarketIndexVO> innerIndexAll() {
        //获取上证指数和深证指数的大盘编码
        List<String> ids = makerIndexProperties.getInner();
        //指定当前时间
        //获取距离当前时间最近的有效股票交易时间
        LocalDateTime last = DateTimeUtil.getLastDateTime4Stock(LocalDateTime.now());
        //TODO 模拟数据
        String mockDate = "20211226105600";
        last = LocalDateTime.parse(mockDate, DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));

        //查询数据库stock_market_log_price
        //根据大盘编码 和指定时间 查询stock_market_index_info 表股票大盘数据详情表
        List<StockMarketIndexInfo> stockMarketIndexInfoList = marketIndexInfoMapper.selectByIAndTime(ids,last);
        //更具大盘编码和指定日期 查询stock_market_log_price 表 大盘开盘价和收盘价流水表
        List<StockMarketLogPrice> stockMarketLogPriceList = marketLogPriceMapper.selectByIdsAndDate(ids,last.toLocalDate());
        return stockMarketIndexInfoList.stream().map((info)->{
            MarketIndexVO vo = MarketIndexVO.builder().build();
            vo.setCode(info.getMarkId());
            vo.setName(info.getMarkName());
            vo.setCurDate(info.getCurTime().toLocalDate().toString());
            vo.setTradeAmt(info.getTradeAccount());
            vo.setTradePrice(info.getCurrentPrice());
            vo.setTradeVol(info.getTradeVolume());
            vo.setUpDown(info.getUpdownRate());
            stockMarketLogPriceList.forEach((logPrice)->{
                if(info.getMarkId().equals(logPrice.getMarketCode())){
                    vo.setOpenPrice(logPrice.getOpenPrice());
                    vo.setPreClosePrice(logPrice.getPreClosePrice());
                }else{
                    vo.setOpenPrice(BigDecimal.ZERO);
                    vo.setPreClosePrice(BigDecimal.ZERO);
                }
            });
            return vo;
        }).toList();
    }




    @Override
    public List<StockBusiness> getStockBusiness() {
        System.out.println("StockServiceImpl.getStockBusiness");
        return stockBusinessMapper.selectAll();
    }



}
